home *** CD-ROM | disk | FTP | other *** search
- ;; Eulisp Module
- ;; Author: pab
- ;; File: threads.em
- ;; Date: Mon Jun 28 17:18:22 1993
- ;;
- ;; Project:
- ;; Description:
- ;; Higher level thread operations.
- ;; Mostly deal with signals, initialization and printing
-
- (defmodule threads
- (defs
- init
- list-fns
- (rename ((open-primitive-semaphore lock)
- (close-primitive-semaphore unlock))
- semaphores)
- )
- ()
-
- (export <thread> threadp thread-reschedule current-thread thread-start
- thread-value <thread-condition> <wrong-thread-continue>)
-
- (defclass <thread-condition> (<condition>)
- ()
- )
-
- (defun open-semaphore-with-signals (isem)
- (or (lock isem)
- (progn (handle-pending-signals)
- (open-semaphore-with-signals isem))))
-
- (defun thread-reschedule ()
- (sys-thread-reschedule)
- (handle-pending-signals))
-
- (defun thread-value (thread)
- (let ((res (sys-thread-value thread)))
- (if (cdr res) (car res)
- (progn (handle-pending-signals)
- (thread-value thread)))))
-
- (defun thread-suspend ()
- (sys-thread-suspend)
- (handle-pending-signals))
-
- ;; NB: it is impossible to raise a non-continuable error on a thread...
- (defun thread-signal (cond fn thread)
- (let ((sem (car (thread-signals thread))))
- (lock sem)
- ((setter thread-signals) thread
- (nconc (thread-signals thread) (cons cond fn)))
- (unlock sem))
- (if (eq (current-thread) thread)
- (handle-pending-signals)
- nil))
-
- (defun handle-pending-signals ()
- (let ((thread-signals (thread-signals (current-thread))))
- (lock (car thread-signals))
- (let ((lst (copy-list (cdr thread-signals))))
- ((setter cdr) thread-signals nil)
- (unlock (car thread-signals))
- (mapcar (lambda (cond)
- (let/cc next
- (internal-signal (car cond) next)))
- lst)
- nil)))
-
- (defconstant sig-table (make-table)
-
- (defun internal-thread-signal (thread flags)
- (do (lambda (key elt)
- (if elt (thread-signal thread nil
- (make (table-ref sig-table)))
- nil))
- (convert flags bit-vector)))
-
- ((setter signal-handler) thread-signal)
-
- ;; Thread Junk. Doesn't belong, but nowhere better for it..
- (defmethod allocate ((x <thread-class>) lst)
- (generic_allocate_instance\,Thread_Class x lst))
-
- (defmethod initialize ((x <thread>) lst)
- (let ((new (call-next-method)))
- (initialize-thread new lst)
- ((setter thread-signals) new
- (cons (make-primitive-semaphore) nil))
- new))
-
- (add-method generic-prin
- (make <method>
- 'signature (list <thread> <object>)
- 'function (method-lambda (thread s)
- (let ((state (thread-state thread)))
- (format s "#<~a: ~u ~a ~a>"
- (class-name (class-of thread))
- thread state
- (if (eq state 'returned)
- (thread-value thread)
- "{undetermined}"))))))
-
-
-
- ;; end module
- )
-